package com.zdsoft.site;

/**
 * 经常有一个对象都是有一个Int类型的字段，用于给该对象进行打标。
 *  一个int类型是32位， 就说明 这样的一个字段，可以被打上32个标 , 每一个标占1位
 *  0表示未被打标，1表示已被打标。 从右往左分别是1位，2位，3位。。。。32位
 *  主要提供以下几种功能
 *  1、给某个数的某1位或者某几位打标
 *  2、移除某个数的某1位或某几位的标
 *  3、检查某个数的某1位或某几位是否都被打标.
 *  @author cqyhm
 */
public class FlagBitUtil {

	public static final int FULL_FLAG = 0XFFFFFFFF;

	/**
	 * 打标某1位
	 * 例子： sign(flag,1) 把flag的1位打标
	 * @param falg
	 *            需要打标的源数
	 * @param offset
	 *            标位(1-32)
	 * @return 打标之后的结果
	 */
	public static int sign(int flag, int offset) {
		int offsetT = 1 << (offset - 1);
		return flag | offsetT;
	}

	/**
	 * 打标某几位
	 * 比如：sign(flag,1,2,3) 把flag的1、2、3位都打标
	 * 
	 * @param flag
	 *            需要打标的源数
	 * @param offsets
	 *            标位(1-32),可变参数，这里可以同时指定多个逗号隔开
	 * @return 打标之后的结果
	 */
	public static int sign(int flag, int... offsets) {
		for (int i = 0; i < offsets.length; i++) {
			flag = sign(flag, offsets[i]);
		}
		return flag;
	}
	/**
	 * 去标某1位
	 * 例子:unsign(flag,1); //把flag的1位去标
	 * @param falg
	 *            需要移除标的源数
	 * @param offset
	 *            标位 (1-32)
	 * @return 移除标位之后的结果
	 */
	public static int unSign(int flag, int offset) {
		int offsetT = 1 << (offset - 1);
		offsetT = FULL_FLAG ^ offsetT;
		return flag & offsetT;
	}

	/**
	 * 去标某几位
	 * 例子:unsign(flag,1,2,3); //把flag的1、2、3位都去标
	 * @param flag
	 *            需要移除标的源数
	 * @param offsets
	 *            标位 (1-32)可变参数，这里可以同时指定多个逗号隔开
	 * @return 移除标位之后的结果
	 */
	public static int unSign(int flag, int... offsets) {
		for (int i = 0; i < offsets.length; i++) {
			flag = unSign(flag, offsets[i]);
		}
		return flag;
	}

	/**
	 * 检查标位是否被打标
	 * 
	 * @param flag
	 *            需要检查标的源数
	 * @param offset
	 *            标位
	 * @return 该标位是否被打标 (1-32)
	 */
	public static boolean checkSign(int flag, int offset) {
		int offsetT = 1 << (offset - 1);
		return (flag & offsetT) == offsetT;
	}

	/**
	 * 检查多个标位是否被打标,全部都是打标才会返回true
	 * 
	 * @param flag
	 *            需要检查标的源数
	 * @param offsets
	 *            标位,可以指定多个，可变参数
	 * @return 指定的多个标位是否都被打标 (1-32)
	 */
	public static boolean checkSign(int flag, int... offsets) {
		for (int i = 0; i < offsets.length; i++) {
			if (!checkSign(flag, offsets[i])) {
				return false;
			}
		}
		return true;
	}
	
}
